{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "### 1.不可变和可变参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "函数内部\n",
      "200\n",
      "[1, 2, 3]\n",
      "end\n",
      "99 [4, 5, 6]\n"
     ]
    }
   ],
   "source": [
    "# 无论传递的参数是可变还是不可变\n",
    "# --只要针对参数\"使用赋值语句\"，会在函数内部修改局部变量，不会影响到外部变量的引用\n",
    "\n",
    "def demo(num,num_list):\n",
    "    print(\"函数内部\")\n",
    "\n",
    "    #赋值语句\n",
    "    num = 200\n",
    "    num_list=[1,2,3]\n",
    "\n",
    "    print(num)\n",
    "    print(num_list)\n",
    "    print(\"end\")\n",
    "\n",
    "gl_num = 99\n",
    "gl_list=[4,5,6]\n",
    "demo(gl_num,gl_list)\n",
    "print(gl_num,gl_list)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[6, 7, 0, 1, 2, 3]\n",
      "[6, 7, 0, 1, 2, 3]\n"
     ]
    }
   ],
   "source": [
    "# 如果参数是可变类型，在函数内部，使用\"方法\"修改了数据的内容，外部数据会受影响\n",
    "\n",
    "def mutable(num_list:list):\n",
    "    num_list.extend([1,2,3])\n",
    "    num_list[2] = 0\n",
    "    print(num_list)\n",
    "\n",
    "gl_list = [6,7,8]\n",
    "mutable(gl_list)\n",
    "print(gl_list)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 2.缺省参数"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[3, 6, 9]\n"
     ]
    }
   ],
   "source": [
    "# 定义函数时，可以给某个参数指定一个默认值，具有默认值的参数称为缺省参数\n",
    "# 调用函数时，如果没有传入缺省参数的值，则在函数内部使用定义函数时指定的参数默认值\n",
    "# 函数的缺省参数，将常见的值设置为参数的缺省值，从而简化函数的调用\n",
    "# e.g.列表排序的方法默认为升序\n",
    "gl_num_list = [6,3,9]\n",
    "gl_num_list.sort()\n",
    "print(gl_num_list)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "何子悠 是 男生\n"
     ]
    }
   ],
   "source": [
    "# 指定函数的缺省参数\n",
    "# 在参数后使用赋值语句，可以指定参数的缺省值\n",
    "def print_info(name,gender=True):\n",
    "    gender_text = '男生'\n",
    "    if not gender:\n",
    "        gender_text = '女生'\n",
    "    print(\"%s 是 %s\"%(name,gender_text))\n",
    "\n",
    "print_info(\"何子悠\")\n",
    "\n",
    "# 缺省参数，需要使用最常见的最为默认值\n",
    "# 如果一个参数的值不确定，则不应该设置默认值，具体的数值在调用函数时由外界传递"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "##### 缺省参数的注意事项\n",
    "##### 1）缺省参数的定义位置\n",
    "##### •带有默认值的缺省参数在列表的末尾\n",
    "##### def print_info(name,title,gender=True)\n",
    "##### 2)调用带有多个缺省参数的函数\n",
    "##### •多参个缺省函数需要指定数名，解释器才知道参数的对应关系(如果都不指定是可以的，若制定了一个，其余必须全部指定)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "何子悠是男生\n"
     ]
    }
   ],
   "source": [
    "def print_info(name,title = '',gender=True):\n",
    "    \"\"\"\n",
    "\n",
    "    :param name: 班上同学的姓名\n",
    "    :param title:职位\n",
    "    :param gender:性别 男生True 女生False\n",
    "    :return:\n",
    "    \"\"\"\n",
    "    gender_text = '男生'\n",
    "    if not gender:\n",
    "        gender_text = '女生'\n",
    "    print(\"%s%s是%s\"%(title,name,gender_text))\n",
    "\n",
    "# 制定了一个，其余必须全部指定\n",
    "# print_info(name=\"黑自由\",\"班长\")\n",
    "print_info(name = '何子悠')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 3.多值参数"
   ],
   "metadata": {
    "collapsed": false
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "(1, 2, 3, 4, 5)\n",
      "{'name': '小明', 'gender': '男'}\n"
     ]
    }
   ],
   "source": [
    "# 函数需要处理的参数是不确定的\n",
    "# python中有两种多值参数\n",
    "# - 参数名前一个*可以接收元组\n",
    "# - 参数名前两个*可以接收字典\n",
    "# - 习惯使用 *args (arguments);**kwargs (kw -> keyword)\n",
    "# - *args 必须在 **kwargs 前面\n",
    "def demo(num,*args,**kwargs):\n",
    "    print(num)\n",
    "    print(args)\n",
    "    print(kwargs)\n",
    "\n",
    "demo(1,1,2,3,4,5,name=\"小明\",gender=\"男\")"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "data": {
      "text/plain": "45"
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 需求\n",
    "# 1.定义一个函数sum_numbers,可以接受的任意多个整数\n",
    "# 2.功能要求：将传递的所有数据累加并且返回累加的结果\n",
    "\n",
    "def  sum_numbers(*args):\n",
    "    sum = 0\n",
    "    for i in args:\n",
    "        sum += i\n",
    "    return sum\n",
    "\n",
    "sum_numbers(1,2,3,4,5,6,7,8,9)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% practice\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[789, 0]\n",
      "(1, 2, 3, 4, 5)\n",
      "{'name': '小明', 'title': '班长'}\n"
     ]
    }
   ],
   "source": [
    "# 元组和字典的拆包\n",
    "# 在调用多值函数是，希望直接将元组和字典传入，就可以使用拆包，简化参数的传递\n",
    "# --在元祖变量前加*\n",
    "# --在字典变量前加**\n",
    "def demo(num,*args,**kwargs):\n",
    "    print(num)\n",
    "    print(args)\n",
    "    print(kwargs)\n",
    "\n",
    "list_info = [789,0]\n",
    "tuple_info=(1,2,3,4,5)\n",
    "dict_info = {\"name\":\"小明\",\"title\":\"班长\"}\n",
    "demo(list_info,*tuple_info,**dict_info)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 4.函数的递归"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n",
      "2\n",
      "1\n"
     ]
    },
    {
     "data": {
      "text/plain": "15"
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 函数调用自身\n",
    "# 示例代码\n",
    "def sum_numbers(num):\n",
    "    print(num)\n",
    "    # 递归的出口很重要，否则会出现死循环\n",
    "    if num == 1:\n",
    "        return\n",
    "    sum_numbers(num-1)\n",
    "\n",
    "sum_numbers(3)\n",
    "\n",
    "# 计算数字累加\n",
    "\n",
    "# 需求：\n",
    "# 1.定义一个函数sum_numbers\n",
    "# 2.能够接收一个num的整数参数\n",
    "# 3.计算1+2+。。。num\n",
    "\n",
    "def sum_numbers(num):\n",
    "    if num == 1:\n",
    "        return 1\n",
    "    temp = sum_numbers(num - 1)\n",
    "    return num + temp\n",
    "\n",
    "sum_numbers(5)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}